---	Improved Castingbar
--	-----------------------------------------------------------------
--	version:	0.6 | 2009-01-24
--	author:		thek
--	contact:	thek - at - nineteen81.de
--	license:	Beerware
--				thek wrote this file. As long as you retain this
--				notice you can do whatever you want with this stuff. 
--				If we meet some day, and you think this stuff is 
--				worth it, you can buy me a beer.
--	-----------------------------------------------------------------
local current = "0.6";
--	-----------------------------------------------------------------
local SetupCastingBar = function(pa, noLag)
	-- create drag & drop frame
	local f = CreateFrame("Frame");
	f.text = f:CreateFontString(nil, "BACKGROUND", "GameFontNormal");
	f.text:SetPoint("CENTER", f, "CENTER", 0, 0);
	f.text:SetText(tostring(pa));
	f:SetPoint(IMPCASTBAR[pa].point, IMPCASTBAR[pa].parent, IMPCASTBAR[pa].rel_point, IMPCASTBAR[pa].x, IMPCASTBAR[pa].y);
	f:SetWidth(getglobal(pa):GetWidth() + 10);
	f:SetHeight(getglobal(pa):GetHeight() + 10);
	f:SetBackdrop({
		bgFile = "Interface/Tooltips/UI-Tooltip-Background",
		edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
		tile = true,
		tileSize = 16,
		edgeSize = 16,
		insets = { left = 5, right = 5, top = 5, bottom = 5 }
	})
	f:SetBackdropColor(0,0,0,0.8);
	f:SetBackdropBorderColor(1,1,1,1);
	f:EnableMouse(true)
	f:SetMovable(true);
	f:RegisterForDrag("LeftButton");
	f:SetScript("OnDragStart", function(self)
		self:StartMoving();
	end);
	f:SetScript("OnDragStop", function(self)
		self:StopMovingOrSizing();
		IMPCASTBAR[pa].moved = true;	-- this bar has been moved
		IMPCASTBAR[pa].point, IMPCASTBAR[pa].parent, IMPCASTBAR[pa].rel_point, IMPCASTBAR[pa].x, IMPCASTBAR[pa].y = self:GetPoint();
	end);
	getglobal(pa):SetMovable(true);
	getglobal(pa):SetUserPlaced(true);
	f:Hide();
	-- manage castingbar position
	hooksecurefunc(getglobal(pa), "Show", function()
		getglobal(pa):ClearAllPoints();
		getglobal(pa):SetPoint(IMPCASTBAR[pa].point, f);
	end);
	-- create lagmeter
	if ( not noLag ) then
		local l = getglobal(pa):CreateTexture(nil, "BACKGROUND");
		l:SetHeight(getglobal(pa):GetHeight());
		l:SetWidth(0);
		l:SetPoint("RIGHT", getglobal(pa), "RIGHT", 0, 0);
		l:SetTexture(1, 0, 0, 1);
	-- manage lagmeter
		hooksecurefunc(getglobal(pa), "Show", function()
			local down, up, lag = GetNetStats();
			local castingmin, castingmax = getglobal(pa):GetMinMaxValues();
			local lagvalue = ( lag / 1000 ) / ( castingmax - castingmin );
			if ( lagvalue < 0 ) then lagvalue = 0; elseif ( lagvalue > 1 ) then lagvalue = 1; end;
			if ( getglobal(pa).channeling ) then
				l:ClearAllPoints();
				l:SetPoint("LEFT", getglobal(pa), "LEFT", 0, 0);
			else
				l:ClearAllPoints();
				l:SetPoint("RIGHT", getglobal(pa), "RIGHT", 0, 0);
			end;
			l:SetWidth(getglobal(pa):GetWidth() * lagvalue);
		end);
	end;
	return f;
end;

--- create Castbartimers
--	-----------------------------------------------------------------
local CreateCastbarTimer = function(pa)
	getglobal(pa).timer = getglobal(pa):CreateFontString(nil, "ARTWORK", "GameFontHighlight");
	getglobal(pa).timer:SetPoint("LEFT", getglobal(pa), "RIGHT", 10, 2);
	getglobal(pa).nextupdate = 0.1;
end;

--- show / hide drag & drop frames
--	-----------------------------------------------------------------
local ToggleAnchors = function()
	if ( pcb:IsShown() ) then pcb:Hide(); tcb:Hide(); fcb:Hide(); mcb:Hide() else pcb:Show(); tcb:Show(); fcb:Show(); mcb:Show() end;
end;

--- show / hide castbaricon
--	-----------------------------------------------------------------
local ToggleIcon = function()
	if ( IMPCASTBAR.icon ) then CastingBarFrameIcon:Show(); else CastingBarFrameIcon:Hide(); end;
end;
-- here we go...
do
	--- saved Vars
	--	-----------------------------------------------------------------
	local SetupDefaultValues = function()
		IMPCASTBAR = {};
		IMPCASTBAR.version 	= current;
		IMPCASTBAR.icon		= true;
		IMPCASTBAR.timer	= true;
		IMPCASTBAR["CastingBarFrame"] 		= {point = "BOTTOM", parent = "UIParent", rel_point = "BOTTOM", x = 0, y = 115, moved = false};
		IMPCASTBAR["TargetFrameSpellBar"] 	= {point = "LEFT", parent = "TargetFrame", rel_point = "RIGHT", x = -15, y = 0, moved = false};
		IMPCASTBAR["FocusFrameSpellBar"] 	= {point = "BOTTOM", parent = "FocusFrame", rel_point = "BOTTOM", x = 0, y = -30, moved = false};
		IMPCASTBAR["MirrorTimer1"]			= {point = "TOP", parent = "UIParent", rel_point = "TOP", x = 0, y = -96, moved = false};
	end;

	--- init addon
	--	-----------------------------------------------------------------
	local f = CreateFrame("Frame");
	f:RegisterEvent("VARIABLES_LOADED");
	f:SetScript("OnEvent", function(self, event)
		if ( event == "VARIABLES_LOADED" ) then
			self:UnregisterEvent(event);
			if ( not IMPCASTBAR or IMPCASTBAR.version ~= current ) then SetupDefaultValues() end;
			-- castbar icon
			ToggleIcon();
			CastingBarFrameIcon:SetPoint("RIGHT", CastingBarFrame, "LEFT", -5, 2);
			CastingBarFrameIcon:SetWidth(28); 
			CastingBarFrameIcon:SetHeight(28);
			-- setup Castingbars
			pcb = SetupCastingBar("CastingBarFrame");
			tcb = SetupCastingBar("TargetFrameSpellBar");
			fcb = SetupCastingBar("FocusFrameSpellBar");
			mcb = SetupCastingBar("MirrorTimer1", true);
			-- setup Castingbartimer
			CreateCastbarTimer("CastingBarFrame");
			CreateCastbarTimer("TargetFrameSpellBar");
			CreateCastbarTimer("FocusFrameSpellBar");
			CreateCastbarTimer("PetCastingBarFrame");
			CreateCastbarTimer("MirrorTimer1");
			-- slash commands
			SLASH_IMPCASTBAR1 = "/icb";
			SlashCmdList["IMPCASTBAR"] = function(arg)
				local arg = string.lower(arg);
				local args = {};
				for s in string.gmatch(arg, "[^%s]+") do
					table.insert(args,s);
				end
				if ( args[1] == "lock" ) then
					ToggleAnchors();
				elseif ( args[1] == "icon" ) then
					IMPCASTBAR.icon = not IMPCASTBAR.icon;
					ToggleIcon();
				elseif ( args[1] == "timer" ) then
					IMPCASTBAR.timer = not IMPCASTBAR.timer;
				elseif ( args[1] == "reset" ) then
					StaticPopupDialogs["IMPCASTBAR_RESET"] = {
						text = "Reset Improved Castingbar and reload your UI?",
						button1 = "Yes",
						button2 = "No",
						OnAccept = function()
							ToggleAnchors();
							SetupDefaultValues();
							ReloadUI();
						end,
						timeout = 0,
						whileDead = 1,
						hideOnEscape = 1
					};
					StaticPopup_Show ("IMPCASTBAR_RESET");			
				else 
					print("Improved Castingbar Configuration")
					print(" [lock] toggles drag 'n' drop frames");
					print(" [icon] toggles castingbar icon");
					print(" [timer] togglers castingbar timers");
					print(" [reset] resets the addon to default");
				end;
            end;
			print("Improved Castingbar loaded... /icb for more information");	
		end;
	end);
	
	---	manage Castingbartimer
	--	-----------------------------------------------------------------
	hooksecurefunc("CastingBarFrame_OnUpdate", function(self, elapsed)
		if ( IMPCASTBAR.timer and self.timer ) then
			if ( self.nextupdate < elapsed ) then
				if ( self.casting ) then
					self.timer:SetText(format("[%.1f]", max(self.maxValue - self.value, 0)));
				elseif ( self.channeling ) then
					self.timer:SetText(format("[%.1f]", max(self.value, 0)));
				else
					self.timer:SetText("");
				end;
				self.nextupdate = 0.1;
			else
				self.nextupdate = self.nextupdate - elapsed;
			end;
		end;
	end);

	--- deny castbar adjusting
	--	-----------------------------------------------------------------------
	function Target_Spellbar_AdjustPosition()	end;
	function Focus_Spellbar_AdjustPosition() 	end;
end;